using System;
using System.Collections.Generic;
using System.Text;
using PSE.Hosting.Management.Common;

namespace PSE.Hosting.Management.Console
{
    class StartAssemblyCommand : ICommand
    {
        // Available option for this command.
        private const string AssemblyPackageOption = "/package";

        private bool ValidateArguments(string[] args, out string[] returnArgs, out bool silentMode)
        {
            returnArgs = null;
            silentMode = false;

            string packageName = String.Empty; // Required option.
            string fileName = String.Empty; // The file name to start (required).

            // Verify if there is a silent mode option.
            // We need to search this option first, to not show any message if errors happens in options,
            // before this option happens.
            for (int i = 1; i < args.Length; i++)
            {
                if (args[i].Equals(Constants.SilentModeOption))
                {
                    silentMode = true;
                }
            }

            for (int i = 1; i < args.Length; i++)
            {
                string[] arg;

                if (args[i].StartsWith("/"))
                {
                    // If the argument starts with '/' then it is an option.

                    // If present bypass the silent option.
                    if (!args[i].Equals(Constants.SilentModeOption))
                    {
                        // Split the string with ':' where the first occurence is the command,
                        // and the second occurence is the value
                        arg = args[i].Split(':');

                        switch (arg[0].Trim().ToLower())
                        {
                            case AssemblyPackageOption:
                                packageName = arg[1].ToUpper();
                                break;

                            default:
                                if (!silentMode)
                                    Messages.InvalidOptionError(arg[0]);
                                return false;
                        }
                    }
                }
                else
                {
                    // It is not an option.
                    // Assume it is the file name.
                    if (String.IsNullOrEmpty(fileName))
                    {
                        fileName = args[i];
                    }
                    else
                    {
                        if (!silentMode)
                            Messages.WriteError("Invalid file name.");
                        return false;
                    }
                }
            }

            // Validations

            // The file name is mandatory.
            if (String.IsNullOrEmpty(fileName))
            {
                if (!silentMode)
                    Messages.NoFileSpecifiedError();
                return false;
            }

            // The package is mandatory.
            if (String.IsNullOrEmpty(packageName))
            {
                if (!silentMode)
                    Messages.NoPackageSpecifiedError();
                return false;
            }
            returnArgs = new string[] { packageName, fileName };

            return true;
        }

        #region ICommand Members

        public void Execute(string[] args)
        {
            string[] returnArgs;
            bool silentMode;

            if (ValidateArguments(args, out returnArgs, out silentMode))
            {
                string packageName = returnArgs[0];
                string fileName = returnArgs[1];

                try
                {
                    ServiceFactory.Instance.GetService().StartAssembly(Constants.ServerName, packageName, fileName);
                }
                catch (InvalidAssemblyException ex)
                {
                    if (!silentMode)
                    {
                        Messages.WriteError(ex.Message);
                    }
                }
                catch (Exception ex)
                {
                    if (!silentMode)
                    {
                        Messages.WriteFailMessage(ex.Message);
                    }
                }
            }
        }

        #endregion
    }
}
